/*
 * Copyright (C) 2011 TopCoder Inc., All Rights Reserved.
 */
package gov.nasa.pds.services.impl;

import java.io.File;

import org.apache.tools.ant.Project;
import org.apache.tools.ant.Target;
import org.apache.tools.ant.taskdefs.Copy;
import org.springframework.beans.factory.InitializingBean;

import com.topcoder.commons.utils.LoggingWrapperUtility;
import com.topcoder.commons.utils.ValidationUtility;
import com.topcoder.util.log.Log;

import gov.nasa.pds.entities.DataFile;
import gov.nasa.pds.services.DataFileCopier;
import gov.nasa.pds.services.DataSetProcessingConfigurationException;
import gov.nasa.pds.services.DataSetProcessingException;

/**
 * <p>
 * The <code>AntDataFileCopier</code> class implements <code>DataFileCopier</code> interface by providing
 * implementation of <code>copyDataFile(DataFile, String)</code> method.
 * </p>
 *
 * <strong>Thread Safety:</strong> This class is mutable since it provides public setter for the logger. But it
 * doesn't change its state and is thread safe when the following conditions are met: this class is initialized by
 * Spring right after construction and its parameters are never changed after that, all entities passed to this class
 * are used by the caller in thread safe manner (accessed from a single thread only).
 *
 * @author KennyAlive
 * @version 1.0
 */
public class AntDataFileCopier implements DataFileCopier, InitializingBean {
    /**
     * Constant for the class name of this class. Used for logging.
     */
    private static final String CLASS_NAME = AntDataFileCopier.class.getName();

    /**
     * <p>
     * The <code>Log</code> instance used for logging.
     * </p>
     *
     * <p>
     * It is initialized with Spring setter dependency injection. Cannot be <code>null</code> after initialization,
     * assuming that property is initialized via Spring setter-based dependency injection and is never changed
     * after that. Has a setter.
     * </p>
     */
    private Log logger;

    /**
     * Creates an instance of <code>AntDataFileCopier</code>
     */
    public AntDataFileCopier() {
        // Empty
    }

    /**
     * Sets the logger.
     *
     * @param logger
     *              the logger to set
     */
    public void setLogger(Log logger) {
        this.logger = logger;
    }

    /**
     * Checks whether this class was initialized by Spring properly.
     *
     * Required parameters:
     * <ul>
     * <li>logger</li>
     * </ul>
     *
     * @throws DataSetProcessingConfigurationException
     *            if the class was not initialized properly
     */
    @Override
    public void afterPropertiesSet() {
        ValidationUtility.checkNotNull(logger, "logger", DataSetProcessingConfigurationException.class);
    }

    /**
     * Copies the file to the stated destination.
     *
     * @param dataFile
     *            - the file to copy.
     * @param destination
     *            - the new destination of the data file.
     * @throws DataSetProcessingException
     *             - if there is an error while doing the copy.
     */
    @Override
    public void copyDataFile(DataFile dataFile, String destination) throws DataSetProcessingException {
        String signature = CLASS_NAME + ".copyDataFile(DataFile dataFile, String destination)";
        LoggingWrapperUtility.logEntrance(logger, signature,
                new String[] {"dataFile", "destination"},
                new Object[] {dataFile.toJSONString(), destination});

        Project project = new Project();
        Target target = new Target();
        Copy copy = new Copy();

        copy.setProject(project);
        copy.setOwningTarget(target);
        copy.setFile(new File(dataFile.getPath()));
        copy.setTofile(new File(destination));

        target.addTask(copy);

        project.addTarget("target", target);
        project.executeTarget("target");

        LoggingWrapperUtility.logExit(logger, signature, null);
    }
}
